/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/container
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AETFixedSizeArray.inl
// Author:		Gianluca Belardelli
// Date:		16/12/2013
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AETFIXEDSIZEARRAY_INL_
#define _AETFIXEDSIZEARRAY_INL_

template <typename T>
AE_FORCEINLINE AETFixedSizeArray<T>::AETFixedSizeArray( void ) {}

template <typename T>
AE_FORCEINLINE AETFixedSizeArray<T>::AETFixedSizeArray( AEINT32 nCapacity, char *lpDescriptor ) : m_nCapacity( nCapacity ),
	m_nSize(0), m_nOverflows(0)
{
	m_lpArray = AEAllocateStack<T>( nCapacity, lpDescriptor );
}

template <typename T>
AE_FORCEINLINE AETFixedSizeArray<T>::AETFixedSizeArray( void* lpBuffer, AEINT32 nBufferSize, const char *lpDescriptor )
{
}

template <typename T>
AE_FORCEINLINE AETFixedSizeArray<T>::~AETFixedSizeArray( void )
{
}

template <typename T>
AE_FORCEINLINE void AETFixedSizeArray<T>::PushBack( const T &tValue )
{
	AEINT32 nSize = m_nSize;

	if( nSize == m_nCapacity )
	{
		nSize--;
		m_nOverflows++;
	}

	m_lpArray[nSize++] = tValue;
	m_nSize = nSize;
}

template <typename T>
AE_FORCEINLINE T& AETFixedSizeArray<T>::Back( void )
{
	AEASSERT( m_nSize > 0 );
	return m_lpArray[ m_nSize -1 ];
}

template <typename T>
AE_FORCEINLINE const T& AETFixedSizeArray<T>::Back( void ) const
{
	AEASSERT( m_nSize > 0 );
	return m_lpArray[ m_nSize -1 ];
}

template <typename T>
AE_FORCEINLINE void AETFixedSizeArray<T>::Clear( void )
{
	m_nSize = 0;
}

template <typename T>
AE_FORCEINLINE void AETFixedSizeArray<T>::RemoveAll( void )
{
}

template <typename T>
AE_FORCEINLINE AEUINT32 AETFixedSizeArray<T>::GetCapacity( void ) const
{
	return m_nCapacity;
}

template <typename T>
AE_FORCEINLINE AEUINT32 AETFixedSizeArray<T>::GetSize( void )
{
	return m_nSize;
}

template <typename T>
AE_FORCEINLINE int AETFixedSizeArray<T>::GetNumOverflows( void ) const
{
	return m_nOverflows;
}

template <typename T>
AE_FORCEINLINE void AETFixedSizeArray<T>::SetSize( AEINT32 nSize )
{
	AEASSERT( nSize <= m_nCapacity );
	m_nSize = nSize;
}

template <typename T>
AE_FORCEINLINE bool AETFixedSizeArray<T>::IsEmpty( void ) const
{
	return m_nSize == 0;
}

template <typename T>
AE_FORCEINLINE bool AETFixedSizeArray<T>::IsFull( void ) const
{
	return m_nSize >= m_nCapacity;
}

template <typename T>
AE_FORCEINLINE T& AETFixedSizeArray<T>::ExpandOne( void )
{
	AEINT32 nSize = m_nSize;

	if( nSize == m_nCapacity )
	{
		nSize--;
		m_nOverflows++;
	}

	T& tResult = m_lpArray[nSize];
	nSize++;
	m_nSize = nSize;

	return tResult;
}

template <typename T>
AE_FORCEINLINE AEINT32 AETFixedSizeArray<T>::IndexOf( const T &tValue ) const
{
	for( AEINT32 i = 0; i < m_nSize; ++i )
	{
		if( m_lpArray[i] == tValue )
			return i;
	}

	return -1;
}

template <typename T>
AE_FORCEINLINE typename AETFixedSizeArray<T>::AEFixedSizeArrayIterator AETFixedSizeArray<T>::Begin( void )
{
	return m_lpArray;
}

template <typename T>
AE_FORCEINLINE typename AETFixedSizeArray<T>::AEFixedSizeArrayIterator AETFixedSizeArray<T>::End( void )
{
	return m_lpArray + m_nSize;
}

template <typename T>
AE_FORCEINLINE typename AETFixedSizeArray<T>::AEFixedSizeArrayIterator_const AETFixedSizeArray<T>::Begin( void ) const
{
	return m_lpArray;
}

template <typename T>
AE_FORCEINLINE typename AETFixedSizeArray<T>::AEFixedSizeArrayIterator_const AETFixedSizeArray<T>::End( void ) const
{
	return m_lpArray + m_nSize;
}

template <typename T>
AE_FORCEINLINE T& AETFixedSizeArray<T>::operator[] ( AEINT32 nIdx )
{
	AEASSERT( nIdx >= 0 && nIdx < m_nSize );
	return m_lpArray[nIdx];
}

template <typename T>
AE_FORCEINLINE const T& AETFixedSizeArray<T>::operator[] ( AEINT32 nIdx ) const
{
	AEASSERT( nIdx >= 0 && nIdx < m_nSize );
	return m_lpArray[nIdx];
}

#endif // _AETFIXEDSIZEARRAY_INL_
